package com.zyy.game.tianlong.network;

import com.zyy.game.tianlong.network.config.NettyConfig;
import com.zyy.game.tianlong.network.callback.GlobalExceptionCallBack;
import com.zyy.game.tianlong.network.exception.ThreadRejectedException;
import io.netty.channel.ChannelInitializer;
import io.netty.util.NettyRuntime;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.EventExecutorGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author relufi
 * @date 2019/7/29 0029
 */
@Configuration
@Slf4j
public class NettyAutoConfig {
    @Bean
    public EventExecutorGroup eventExecutorGroup(NettyConfig nettyConfig) {
        //business 线程
        int businessGroupCount = nettyConfig.getBusinessGroup();
        return new DefaultEventExecutorGroup(businessGroupCount <= 0 ? NettyRuntime.availableProcessors() * 2 : businessGroupCount,
                new DefaultThreadFactory( "业务线程"), nettyConfig.getBusinessGroupMaxPendingTasks(),
                (task, executor) -> {
                    throw new ThreadRejectedException("业务线程任务队列溢出");
                });
    }

    @Bean
    @ConditionalOnMissingBean(ChannelInitializer.class)
    @ConditionalOnProperty(prefix = "netty", name = "game-protocol", havingValue = "web_socket")
    public ChannelInitializer webSocketChannelInitializer(GlobalExceptionCallBack globalExceptionCallBack, NettyConfig nettyConfig, DefaultEventExecutorGroup businessGroup, GameDispatcher gameMsgHandler) {
        log.info("协议使用 WebSocket");
        return new GameWebSocketChannelInitializer(globalExceptionCallBack, nettyConfig, businessGroup, gameMsgHandler);
    }

    @Bean
    @ConditionalOnMissingBean(ChannelInitializer.class)
    @ConditionalOnProperty(prefix = "netty", name = "game-protocol", havingValue = "length_field")
    public ChannelInitializer lengthFieldChannelInitializer(GlobalExceptionCallBack globalExceptionCallBack, NettyConfig nettyConfig, DefaultEventExecutorGroup businessGroup, GameDispatcher gameMsgHandler) {
        log.info("协议使用 LengthField");
        return new GameLengthFieldChannelInitializer(globalExceptionCallBack, nettyConfig, businessGroup, gameMsgHandler);
    }

}
